package com.suncaper.han_yi_system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suncaper.han_yi_system.mapper.BatchMapper;
import com.suncaper.han_yi_system.mapper.ClothingStyleMapper;
import com.suncaper.han_yi_system.mapper.SizeRecommendationMapper;
import com.suncaper.han_yi_system.pojo.dto.ApplicationQueryDto;
import com.suncaper.han_yi_system.pojo.dto.ClothingStyleDto;
import com.suncaper.han_yi_system.pojo.dto.ClothingStyleQueryDto;
import com.suncaper.han_yi_system.pojo.entity.Batch;
import com.suncaper.han_yi_system.pojo.entity.ClothingStyle;
import com.suncaper.han_yi_system.pojo.entity.SizeRecommendation;
import com.suncaper.han_yi_system.pojo.vo.ClothingStatsVo;
import com.suncaper.han_yi_system.pojo.vo.ClothingStyleVo;
import com.suncaper.han_yi_system.pojo.vo.StyleStatsVo;
import com.suncaper.han_yi_system.service.ClothingStyleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ClothingStyleServiceImpl extends ServiceImpl<ClothingStyleMapper, ClothingStyle> implements ClothingStyleService {

    @Autowired
    BatchMapper batchMapper;

    @Autowired
    ClothingStyleMapper clothingStyleMapper;

    @Autowired
    SizeRecommendationMapper sizeRecommendationMapper;

    @Override
    public Page<ClothingStyleVo> pageList(ClothingStyleQueryDto clothingStyleDto) {
        Page<ClothingStyleVo> page = new Page<>(clothingStyleDto.getPage(), clothingStyleDto.getLimit());
        Page<ClothingStyleVo> clothingStyleVoPage = clothingStyleMapper.pageList(page, clothingStyleDto);
        for (ClothingStyleVo clothingStyleVo : clothingStyleVoPage.getRecords()) {
            clothingStyleVo.setSizes((sizeRecommendationMapper.selectByStyleId(clothingStyleVo.getId())));
        }
        return clothingStyleVoPage;
    }

    @Override
    @Transactional
    public void saveWithSize(ClothingStyleDto clothingStyleDto) {
        ClothingStyle cs = ClothingStyle.builder()
                .name(clothingStyleDto.getName())
                .genderLimit(clothingStyleDto.getGenderLimit())
                .image(clothingStyleDto.getImage())
                .build();

        clothingStyleMapper.insert(cs);

        List<SizeRecommendation> sizes = clothingStyleDto.getSizes();

        if (sizes != null && sizes.size() > 0) {
            for (SizeRecommendation sizeRecommendation : sizes) {
                sizeRecommendation.setStyleId(cs.getId());
                sizeRecommendationMapper.insert(sizeRecommendation);
            }
        }
    }

    @Override
    public List<SizeRecommendation> getByStyleId(Long id) {
        return sizeRecommendationMapper.selectByStyleId(id);
    }

    @Override
    @Transactional
    public void removeWithSize(Long id) {
        clothingStyleMapper.deleteById(id);
        sizeRecommendationMapper.deleteByStyleId(id);
    }

    @Override
    @Transactional
    public void updateWithSize(ClothingStyleDto clothingStyleDto) {
        ClothingStyle cs = new ClothingStyle();
        BeanUtils.copyProperties(clothingStyleDto, cs);

        clothingStyleMapper.updateById(cs);

        sizeRecommendationMapper.deleteByStyleId(cs.getId());

        List<SizeRecommendation> sizes = clothingStyleDto.getSizes();
        if (sizes != null && sizes.size() > 0) {
            for (SizeRecommendation sizeRecommendation : sizes) {
                sizeRecommendation.setStyleId(cs.getId());
                sizeRecommendationMapper.insert(sizeRecommendation);
            }
        }
    }

    @Override
    public Map<String,Object> getClothingStats(ApplicationQueryDto applicationQueryDto) {
        Map<String,Object> map = new HashMap<>();
        ClothingStatsVo clothingStatsVo = new ClothingStatsVo();

        List<Long> ids = null;

        if(applicationQueryDto.getAcademicYear() != null){
            List<Batch> batches = batchMapper.selectList(new QueryWrapper<Batch>()
                    .eq("academic_year", applicationQueryDto.getAcademicYear()));

            ids = batches.stream().map(Batch::getId).toList();
        }

        List<StyleStatsVo> styleStatsVos = getBaseMapper().findByBatchIds(ids, applicationQueryDto.getAcademicYear());
        List<ClothingStyle> clothingStyles = styleStatsVos.stream().map(styleStatsVo -> {
            ClothingStyle clothingStyle = new ClothingStyle();
            clothingStyle.setId(styleStatsVo.getId());
            clothingStyle.setGenderLimit(styleStatsVo.getGenderLimit());
            return clothingStyle;
        }).distinct().toList();
        int male = 0;
        int female = 0;
        int unlimited = 0;

        for (ClothingStyle clothingStyle : clothingStyles) {
            switch (clothingStyle.getGenderLimit()) {
                case 2:
                    male++;
                    break;
                case 1:
                    female++;
                    break;
                default:
                    unlimited++;
            }
        }
        clothingStatsVo.setManCount(male);
        clothingStatsVo.setWomanCount(female);
        clothingStatsVo.setGenderCount(unlimited);
        clothingStatsVo.setAllCount((long) male+female+unlimited);
        map.put("clothingStatsVo", clothingStatsVo);

        //-------------------------

        for (StyleStatsVo styleStatsVo : styleStatsVos) {
            styleStatsVo.setSizeVos(sizeRecommendationMapper
                    .findCountByStyleId(styleStatsVo.getId(),
                            applicationQueryDto.getCollegeId(),
                            styleStatsVo.getAcademicYear()));
            styleStatsVo.getCount();
        }
        map.put("styleStatsVos", styleStatsVos);

        return map;
    }

    @Override
    public List<ClothingStyle> getClothingStyleList(Long batchId) {
        return getBaseMapper().findListByBatchId(batchId);
    }


}